package com.xyy.saas.payment.adpater.pingan.callback;

import com.alibaba.fastjson.JSON;
import com.xyy.saas.payment.adpater.pingxx.domain.PayDO;
import com.xyy.saas.payment.callback.core.handler.CastRequestHandler;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.FBankPowerIdEnum;
import com.xyy.saas.payment.cores.enums.PayModeEnum;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.dao.model.PrePayOrder;
import com.xyy.saas.payment.payment.core.service.PrePayOrderService;
import com.xyy.saas.payment.service.ThirdUserInfoService;
import com.xyy.saas.payment.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Component
@Slf4j
public class CasePinganRequestHandler implements CastRequestHandler {
    @Resource
    private ThirdUserInfoService thirdUserInfoService;
    @Resource
    private PrePayOrderService prePayOrderService;

    /**
     * 渠道
     */
    @Override
    public String getChannel() {
        return Constants.CHANNEL_PINGAN_NAME;
    }

    /**
     * 对象转换
     */
    @Override
    public Object castRequestHandler(String method, Map<String, String> request, HttpServletRequest requestMsg) throws Exception {
        switch (method) {
            case Constants.METHOD_PAY_SUCCESS_NAME:
                return castToPayDO(request);
        }

        throw new UnsupportedOperationException("Not support pingan callback method " + method);
    }

    /**
     * 支付
     */
    private PayDO castToPayDO(Map<String, String> request) throws PaymentException {
        /**
         * 1 支付
         * 2 退款
         * 3 撤销
         */
        String orderType = request.get("OrderType");
        /**
         * 0 已受理
         * 1 交易成功
         * 2 交易中
         * 3 用户支付中
         * 4 交易关闭
         * 9 已撤销
         */
        String orderStatus = request.get("OrderStatus");

        if(!"1".equals(orderType) || !"1".equals(orderStatus)) {
            throw new PaymentException(ResultCodeEnum.PINGAN_IGNORE_ERROR);
        }

        PayDO payDO = new PayDO();
        String payNo = request.get("TraderOrderNo");

        if(payNo.startsWith(Constants.TOTAL_ORDER_NUMBER_PREFIX)) {
            payNo =  payNo.substring(Constants.TOTAL_ORDER_NUMBER_PREFIX.length());
        }

        payDO.setOrderNo(payNo);
        payDO.setChannelChargeNo(request.get("BankOrderNo"));
        payDO.setAmount(Integer.parseInt(request.get("TranAmt")));
        FBankPowerIdEnum powerId = FBankPowerIdEnum.getPowerIdById(request.get("PayModeNo"));
        payDO.setChannel(Constants.CHANNEL_PINGAN_NAME + "_" + powerId.getChannel());

        if(FBankPowerIdEnum.PINGAN_ALIPAY_MINI == powerId || FBankPowerIdEnum.PINGAN_WX_MINI == powerId) {
            payDO.setPayMode(PayModeEnum.MINI.getMode());
        }
        else if(FBankPowerIdEnum.PINGAN_WX_OFFICIAL == powerId) {
            payDO.setPayMode(PayModeEnum.PUB.getMode());
        }
        else if(FBankPowerIdEnum.PINGAN_CREDIT == powerId) {
            PrePayOrder prePayOrder = prePayOrderService.getPrePayOrderByPayNo(payNo);

            if(prePayOrder.getExtra().contains("frontSkipUrl")) {
                payDO.setPayMode(PayModeEnum.PC.getMode());
            }
            else {
                payDO.setPayMode(PayModeEnum.APP.getMode());
            }
        }

        // payDO.setMchId();
        payDO.setResultCode("SUCCESS");
        payDO.setChannelTransactionNo(request.get("ChannelOrderNo"));

        try {
            payDO.setTimePaid(DateUtil.parase(request.get("PaySuccessTime"), DateUtil.YYYYMMDDHHMMSS));
        }
        catch(Exception e) {
            log.error("CasePinganRequestHandler#castToPayDo cast time error request:{}", JSON.toJSONString(request));
        }

        return payDO;
    }
}
